package com.membership.cloud.web;

import com.membership.cloud.exception.InvalidItemException;
import com.membership.cloud.exception.InvalidItemException;
import com.membership.cloud.exception.ServerTechnicalException;
import com.membership.cloud.exception.UnauthenticatedException;
import com.membership.cloud.exception.UnauthorizedException;
import com.membership.cloud.service.SecurityService;
import com.membership.cloud.service.UserService;
import com.membership.cloud.web.model.UserPageResponse;
import com.membership.cloud.web.model.UserResponse;
import com.membership.cloud.web.model.UserSessionInfo;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/security")
public class SecurityController implements ControllerConstant {

    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityController.class);

    @Autowired
    private UserService userService;
    @Autowired
    private SecurityService securityService;

    @RequestMapping(value = "/user",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public UserPageResponse getUser(
            @RequestParam(value = "id", required = false, defaultValue = NEGATIVE) int id,
            @RequestParam(value = "name", required = false, defaultValue = EMPTY) String name,
            @RequestParam(value = "fullName", required = false, defaultValue = EMPTY) String fullName,
            @RequestParam(value = "page", required = false, defaultValue = DEFAULT_PAGE) int page,
            @RequestParam(value = "pageSize", required = false, defaultValue = DEFAULT_PAGE_SIZE) int pageSize)
            throws ServerTechnicalException, UnauthorizedException, UnauthenticatedException {

        /**
         * Exception handling example
         */
//        if (LOGGER.isInfoEnabled()) {
//            LOGGER.info("get all user, paging");
//        }
//        try {
//            if (true)
//                throw new NullPointerException("null point roi");
//        } catch (Exception e) {
//            LOGGER.error("Error while processing something", e);
//            throw new ServerTechnicalException("Error while processing your request. Please try again later", e);
//        }

        // Only admin and manager can get user list
        securityService.validateCurrentRole(UserSessionInfo.Role.ADMIN, UserSessionInfo.Role.MANAGER);
        UserPageResponse userPageResponse = userService.get(id, name, fullName, page, pageSize);
        return userPageResponse;
    }

    @RequestMapping(value = "/auth",
            method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public UserResponse auth(
            @RequestHeader(value = "Authorization", required = false, defaultValue = EMPTY) String authorization)
            throws UnauthorizedException, InvalidItemException,
            MissingServletRequestParameterException, ServerTechnicalException {

        if (StringUtils.isEmpty(authorization)) {
            // Hide the Authorization header from being known by unauthorized accesses
            // Make them believe there is a required parameter named 'credentials'
            throw new MissingServletRequestParameterException("credentials", "String");
        }

        UserResponse userResponse = securityService.authorize(authorization);
        return userResponse;
    }
}
